package interpreter.operation;

import interpreter.Registers;

/**
 * @author Roderland
 * @since 1.0
 */
public class Operand {
    OpType opType;
    int imm;
    int sca;
    Registers reg1;
    Registers reg2;

    public Operand(OpType opType, int imm) {
        this.opType = opType;
        this.imm = imm;
    }

    public Operand(OpType opType, Registers reg1) {
        this.opType = opType;
        this.reg1 = reg1;
    }

    public Object decode() {
        int virtualAddress = -1;
        switch (opType) {
            case EMPTY: {
                return null;
            }
            case IMM: {
                return imm;
            }
            case REG: {
                return reg1;
            }
            case MM_IMM: {
                virtualAddress = imm;
                break;
            }
            case MM_REG: {
                virtualAddress = reg1.getValue();
                break;
            }
            case MM_IMM_REG: {
                virtualAddress = imm+reg1.getValue();
                break;
            }
            case MM_REG1_REG2: {
                virtualAddress = reg1.getValue()+reg2.getValue();
                break;
            }
            case MM_IMM_REG1_REG2: {
                virtualAddress = imm+reg1.getValue()+reg2.getValue();
                break;
            }
            case MM_REG2_S: {
                virtualAddress = sca*reg2.getValue();
                break;
            }
            case MM_IMM_REG2_S: {
                virtualAddress = sca*reg2.getValue()+imm;
                break;
            }
            case MM_REG1_REG2_S: {
                virtualAddress = sca*reg2.getValue()+reg1.getValue();
                break;
            }
            case MM_IMM_REG1_REG2_S: {
                virtualAddress = sca*reg2.getValue()+reg1.getValue()+imm;
                break;
            }
        }
        return virtualAddress;
    }

    public OpType getOpType() {
        return opType;
    }
}
